package com.shiro.Realm;

import com.entity.Account;
import com.entity.AccountRole;
import com.entity.Permission;

import com.servcice.AccountService;
import com.utils.ContextUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 编写自定义Realm
 * 
 * @author
 *
 */
public class CustomRealm extends AuthorizingRealm {

	/** 用户的业务类 **/
	//@Autowired
	//@Lazy
	private AccountService accountService;

	@Resource
	HttpServletRequest request;
	
 

//	public AccountService getAccountService() {
//		return accountService;
//	}
//
//	public void setAccountService(AccountService accountService) {
//		this.accountService = accountService;
//	}

	/**
	 * 没有登录之前，用户操作检查token使用token（用户和密码的组合）执行登录方法，登录成功将用户名保存到shiro-session中
	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// TODO Auto-generated method stub
		String username = (String) token.getPrincipal();
		// 调用userService查询是否有此用户
		String servicename = request.getParameter("loginOption");
		servicename = Optional.ofNullable(servicename).orElse("student")+"Service";
		accountService = (AccountService) ContextUtils.getSpringMVCContext().getBean(servicename);
		Account account = null;
		try {
			account = accountService.getAccountByAccountName(username);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (account == null) {

			// 抛出 帐号找不到异常
			throw new UnknownAccountException();
		} else {
			System.out.println(username+" "+ account.getPassword() +" "+
			account.getCredentialsSalt()+" mmmmmmmmmmmmmmmmmmmmmm");

		}
		// 判断帐号是否锁定
		if (Boolean.TRUE.equals(account.getLocked())) {
			// 抛出 帐号锁定异常
			throw new LockedAccountException();
		}
		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(account.getAccountname(), // 用户名
				account.getPassword(), // 密码
				ByteSource.Util.bytes(account.getCredentialsSalt()), // salt=username+salt
				getName() // realm name
		);

		return authenticationInfo;
	}

	/**
	 * 已经登录过了，检查用户是有具有权限，是从session得到principalCollection
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		// 获取当前用户
		//
		String accountName = (String) principalCollection.getPrimaryPrincipal();//从session中获得的对象获得用户名
//		String servicename = request.getParameter("loginOtion");
//		System.out.println(servicename + " 11111111----111111111111");
//		servicename = Optional.ofNullable(servicename).orElse("student")+"Service";
//		AccountService accountService = (AccountService) ContextUtils.getSpringMVCContext().getBean(servicename);

		Account account = null;
		try {
			account = (Account) accountService.getAccountByAccountName(accountName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 内置用户:授予所有权限
		List<Permission> permissions = null;
		// if (user != null && user.getUsername().equals("admin")) {
		// permissions = permissionDao.findAll();
		// } else { // 其他普通用户:查出该用户对应的所有权限

		// }

		// 授权
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Set<String> roles = new HashSet<String>();
		for (AccountRole accountRole : account.getAccountRoles()) {
			roles.add(accountRole.getRole().getName());
			for (Permission p : accountRole.getRole().getPermissions()) {
				System.out.println(p.getDescription());
				info.addStringPermission(p.getDescription());
			}
		}
		info.setRoles(roles);
		return info;
	}

	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}

	// /***
	// * 获取授权信息
	// */
	// //根据自己系统规则的需要编写获取授权信息，这里为了快速入门只获取了用户对应角色的资源url信息
	// @Override
	// protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
	// pc) {
	// String accountname = (String)pc.fromRealm(getName()).iterator().next();
	// if(accountname!=null){
	// List<String> pers =
	// studentService.getPermissionsByStudentName(accountname);
	// if(pers!=null && !pers.isEmpty()){
	// SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
	// for(String each:pers){
	// //将权限资源添加到用户信息中
	// info.addStringPermission(each);
	// }
	// }
	// }
	// return null;
	// }
	// /***
	// * 获取认证信息
	// */
	// @Override
	// protected AuthenticationInfo doGetAuthenticationInfo(
	// AuthenticationToken at) throws AuthenticationException {
	//
	//
	// UsernamePasswordToken token = (UsernamePasswordToken) at;
	// // 通过表单接收的用户名
	// String accountname = token.getUsername();
	// if(accountname!=null && !"".equals(accountname)){
	// Account account = studentService.getStudentByName(accountname);
	// if (account != null) {
	// return new SimpleAuthenticationInfo(account.getAccountname(),
	// account.getPassword(), getName());
	// }
	// }
	// return null;
	// }

}